package dev.mcdd.common.json;


import dev.mcdd.common.constant.ResponseType;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * JsonVo
 *
 * @author: mcdd1024
 * @date 2025/1/16 05:21
 */
public record JsonVo(String message, ResponseType type, Map<String, Object> data) {

    private final static String DEFAULT_SUCCESSFUL_MSG = "请求成功";
    private final static String DEFAULT_FAILURE_MSG = "请求失败";

    public static JsonVo success() {
        return success(DEFAULT_SUCCESSFUL_MSG);
    }

    public static JsonVo success(String message) {
        return new JsonVo(message, ResponseType.SUCCESS, new HashMap<>());
    }

    public static JsonVo error(ResponseType type) {
        return error(DEFAULT_FAILURE_MSG, type);
    }

    public static JsonVo error(String message, ResponseType type) {
        if (type == ResponseType.CLIENT_ERROR || type == ResponseType.SERVER_ERROR || type == ResponseType.FORBIDDEN) {
            return new JsonVo(message, type, new HashMap<>());
        }
        throw new IllegalArgumentException(type.name());
    }

    public static JsonVo forbidden(String message) {
        return new JsonVo(message, ResponseType.FORBIDDEN, new HashMap<>());
    }

    public JsonVo add(String key, Object value) {
        Objects.requireNonNull(key);
        this.data.put(key, value);
        return this;
    }

    public void responseToClient(HttpServletResponse response) {
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.println(JsonHelper.toJSON(this));
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            assert writer != null;
            writer.close();
        }
    }

}
